#ifndef __extension_controller_h_
#define __extension_controller_h_
#include "adevs/adevs.h"
#include "io_type.h"
#include "controller.h"

class ExtensionController: public Controller
{
	public:
		/// Constructor.
		ExtensionController();
		/// Internal transition function.
		void delta_int();
		/// External transition function.
		void delta_ext(double e, const adevs::Bag<IO_Type>& xb);
		/// Confluent transition function.
		void delta_conf(const adevs::Bag<IO_Type>& xb);
		/// Output function.
		void output_func(adevs::Bag<IO_Type>& yb);
		/// Time advance function.
		double ta();
		/// Output value garbage collection.
		void gc_output(adevs::Bag<IO_Type>& g);
		/// Destructor.
		~ExtensionController();

		void set_phase_length(int side, double pl) {phase_length[side] = pl;}
		void set_phase_max_length(double pml) {phase_max_length = pml;}
		void set_extension_step(double es) {extension_step = es;}

	private:
		/// Default settings
		static const double DEFAULT_PHASE_LENGTH;
		static const double DEFAULT_PHASE_MAX_LENGTH;
		static const double DEFAULT_EXTENSION_STEP;

		/// Status variables
		double remaining_time;
		int current_side_green;
		double current_phase_length;
		double phase_time;

		/// Setting variables
		double phase_length[4];
		double phase_max_length;
		double extension_step;

		/// Auxiliary methods
		int next_side_green() { return (current_side_green+1) % get_sides_count(); }
};

#endif
